import { app } from "../../scripts/app.js";

import { ComfyDialog, $el } from "../../scripts/ui.js";

import { ComfyWidgets } from "../../../scripts/widgets.js";
const dcw = 768;
const dch = 768;
function get_position_style(ctx, widget_width, y, node_height) {
    const MARGIN = 4 // the margin around the html element

    /* Create a transform that deals with all the scrolling and zooming */
    const elRect = ctx.canvas.getBoundingClientRect()
    const transform = new DOMMatrix()
        .scaleSelf(
            elRect.width / ctx.canvas.width,
            elRect.height / ctx.canvas.height
        )
        .multiplySelf(ctx.getTransform())
        .translateSelf(MARGIN, MARGIN + y)

    return {
        transformOrigin: '0 0',
        transform: transform,
        left: `0`,
        top: `0`,
        cursor: 'pointer',
        position: 'absolute',
        maxWidth: `${widget_width - MARGIN * 2}px`,
        // maxHeight: `${node_height - MARGIN * 2}px`, // we're assuming we have the whole height of the node
        width: `${widget_width - MARGIN * 2}px`,
        // height: `${node_height * 0.3 - MARGIN * 2}px`,
        // background: '#EEEEEE',
        display: 'flex',
        flexDirection: 'column',
        // alignItems: 'center',
        justifyContent: 'space-around'
    }
}

function generateUniqueRandomString() {
    let result = '';
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    const charactersLength = characters.length;
    for (let i = 0; i < 10; i++) { // 生成长度为10的随机字符串
        result += characters.charAt(Math.floor(Math.random() * charactersLength));
    }
    return result;
}



class drawArea {
    canvas = null;
    ctx = null;
    areaList = null;
    width = 512;
    height = 512;
    rectangles = [];
    isDrawing = false;
    currentRect = null;
    dataObj = null;
    constructor(dataObj, canvas, areaList, width = 512, height = 512) {
        this.canvas = canvas;
        this.ctx = canvas.getContext('2d');
        this.ctx.setTransform(1, 0, 0, 1, 0, 0);
        this.areaList = areaList;
        this.width = width;
        this.height = height;
        this.dataObj = dataObj;

        this.canvas.addEventListener('mousedown', (e) => {
            if (e.button !== 0) return; // Ensure it's the left mouse button
            var cw = canvas.width;
            var ch = canvas.height;
            var rate = 1;
            if (cw >= ch && cw > dcw) {
                rate = cw / dcw;
            } else if (ch > dch) {
                rate = ch / dch;
            }
            this.isDrawing = true;
            this.currentRect = {
                id: generateUniqueRandomString(),
                x: e.offsetX,
                y: e.offsetY,
                width: 0,
                height: 0,
                color: `#${Math.floor(Math.random() * 16777215).toString(16)}`
            };
            this.rectangles.push(this.currentRect);
        });


        this.canvas.addEventListener('mouseup', (e) => {
            this.drawEnd(e);
        });

        // 鼠标离开事件
        this.canvas.addEventListener('mouseleave', (e) => {
            if (this.currentRect == null) {
                return;
            }
            this.drawEnd(e);
        });

        // 鼠标移动事件
        this.canvas.addEventListener('mousemove', (e) => {
            if (!this.isDrawing) return;
            const rect = canvas.getBoundingClientRect(); // 获取画布在屏幕上的位置和尺寸
            var cw = canvas.width;
            var ch = canvas.height;
            var rate = 1;
            if (cw >= ch && cw > dcw) {
                rate = cw / dcw;
            } else if (ch > dch) {
                rate = ch / dch;
            }
            console.log(e.offsetX, this.currentRect.x, rate)

            console.log([e.offsetX, e.offsetY], [e.clientX, e.clientY], [rect.left, rect.top]);
            this.currentRect.width = (e.offsetX - this.currentRect.x);
            this.currentRect.height = (e.offsetY - this.currentRect.y);
            // this.currentRect.width = (e.clientX - rect.left) * scaleX;
            // this.currentRect.height = (e.clientY - rect.top) * scaleY;
            this.drawRect(this.currentRect, true); // Draw only the current rectangle stroke
        });
        this.resizeCanvas(width, height);
    }

    resizeCanvas(cw, ch) {
        this.rectangles = [];
        this.areaList.innerHTML = '';
        this.canvas.width = this.width = cw
        this.canvas.height = this.height = ch
        // Clear canvas when resized
        console.log(this.canvas.width, this.canvas.height)
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    }

    // 这里在汇矩形
    drawRect(rect, isStroke = false) {
        this.ctx.fillStyle = rect.color;
        if (!isStroke) {
            this.ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
        } else {
            this.ctx.strokeStyle = '#000';
            this.ctx.lineWidth = 2;
            this.ctx.strokeRect(rect.x, rect.y, rect.width, rect.height);
        }
    }


    // 这里是在画所有的，因为他在清除画布
    draw() {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); // Clear the canvas
        this.rectangles.forEach(rect => this.drawRect(rect));
    }


    drawCurrRect() {
        if (this.currentRect == null) {
            return;
        }
        this.drawRect(currentRect)
    }



    // 绘制结束的时候
    drawEnd(e) {
        if (this.currentRect && (this.currentRect.width !== 0 || this.currentRect.height !== 0)) {
            this.drawRect(this.currentRect); // Fill the color on mouseup
        } else {
            this.rectangles.pop();
        }
        this.isDrawing = false;
        this.draw(); // Redraw all rectangles after finishing the current one
        // this.showAreaList();
        this.addAreaList()
        this.currentRect = null;
        this.dataObj.value = JSON.stringify(this.rectangles);
    }

    addAreaList() {
        var rect = this.currentRect;
        var id = rect.id;
        var html = `<div id="area${id}" class="fcl-area-item">
                <span>Rectangle: X: ${rect.x}, Y: ${rect.y}, W: ${rect.width}, H: ${rect.height}</span>
                <button class="delete-btn" id="delArea${id}">×</button>
            
        </div>`;
        this.areaList.insertAdjacentHTML("beforeend", html)
        let ele = document.querySelector(`#delArea${id}`);
        let that = this;
        ele.addEventListener("click", function (e) {
            e.stopPropagation();
            that.deleteRect(`${id}`)
        })

    }

    deleteRect(index) {
        this.rectangles.splice(index, 1);
        this.draw(); // Redraw the canvas to reflect the change
        document.querySelector(`#area${index}`).remove();
    }

    // Initial resize
    // resizeCanvas();
}

function setSA(cw, ch) {
    /* if (cw >= ch && cw > dcw) {
        var rate = dcw / cw;
        ch = rate * ch
        cw = dcw;
    } else if (ch > dch) {
        var rate = dch / ch;
        cw = rate * cw
        ch = dch;
    } */
    return [cw, ch]
}

function nodeObj(node, nodeName, inputData, app) {
    node.name = nodeName;
    console.log(inputData);
    const widget = {
        type: 'div',
        name: nodeName,
        draw(ctx, node, widget_width, y, widget_height) {
            Object.assign(
                this.div.style,
                get_position_style(ctx, widget_width, y, node.size[1]),
                {
                    flexdirection: "column",
                    justifyContent: 'flex-start'
                }
            )
        },
        parent: node,
    }

    widget.div = $el('div.fcl-select-area', {})
    widget.div.style = ``;



    const addBtn = document.createElement('button')
    addBtn.innerText = 'Reset'
    addBtn.style = `cursor: pointer;
    font-weight: 300;
    margin: 2px; 
    color: var(--descrip-text);
    background-color: var(--comfy-input-bg);
    border-radius: 8px;
    border-color: var(--border-color);
    border-style: solid;height: 30px;min-width: 122px;
   `

    let unique = generateUniqueRandomString();
    // 区域
    const opArea = document.createElement('div')
    opArea.className = 'fcl-area-op';
    opArea.id = "opArea"
    opArea.style = "width:100%;";
    let iwv = inputData.width.value;
    let ihv = inputData.height.value;
    var createCavans = function (unique, cw, ch) {
        console.log(cw, ch, 'sssssssssss')
        const canvas = document.createElement('canvas');
        canvas.width = cw
        canvas.height = ch
        canvas.viewBox = `0 0 ${cw} ${ch}`;
        var rs = setSA(cw, ch)
        cw = rs[0]
        ch = rs[1]
        canvas.style = `width:${cw}px;height:${ch}px;background-color:white;cursor:auto;`;
        canvas.id = "fclanvas_" + unique;

        return canvas
    }
    var canvas = createCavans(unique, iwv, ihv);
    let cavansId = canvas.id

    var createAreaList = (unique) => {
        const areaList = document.createElement('div')
        areaList.className = 'fcl-area-list';
        areaList.id = "areaList_" + unique
        return areaList;

    };
    // 区域
    var areaList = createAreaList(unique)
    let areaListId = areaList.id

    opArea.appendChild(canvas)
    opArea.appendChild(areaList)

    widget.div.appendChild(addBtn)
    widget.div.appendChild(opArea)

    document.body.appendChild(widget.div)

    node.addCustomWidget(widget)
    let drawObj = new drawArea(inputData.area_list, document.querySelector(`#${cavansId}`), document.querySelector(`#${areaListId}`), iwv, ihv)
    addBtn.addEventListener('click', () => {

        iwv = inputData.width.value;
        ihv = inputData.height.value;
        /* unique = generateUniqueRandomString();
        canvas.remove();
        areaList.remove();
        iwv = inputData.width.value;
        ihv = inputData.height.value;
        canvas = createCavans(unique, iwv, ihv);
        cavansId = canvas.id
        areaList = createAreaList(unique)
        areaListId = areaList.id
        opArea.appendChild(canvas)
        opArea.appendChild(areaList)
        drawObj = new drawArea(inputData.area_list, document.querySelector(`#${cavansId}`), document.querySelector(`#${areaListId}`), iwv, ihv) */

        canvas.width = drawObj.canvas.width = iwv;
        canvas.width = drawObj.canvas.width = ihv;

        canvas.style = `width:${iwv}px;height:${ihv}px;background-color:white;cursor:auto;`;
        drawObj.resizeCanvas(iwv, ihv);


    })
    const onRemoved = node.onRemoved;
    node.onRemoved = () => {
        widget.div.remove()
        return onRemoved?.()
    }
    node.serialize_widgets = true //需要保存参数 */


}


app.registerExtension({
    name: "FCL_SELECT_AREA",
    async init(app) {
        const style = document.createElement("style")
        style.innerText = `
        .fcl-select-area{}
        .fcl-area-op{
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            margin-top: 10px;
        }
        .fcl-area-list{
            margin-top: 10px;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: flex-end;
            width: 100%;
        }
        .fcl-area-item button{
            margin-left:10px;
            cursor: pointer;
            font-weight: 300;
            margin: 2px; 
            color: var(--descrip-text);
            background-color: var(--comfy-input-bg);
            border-radius: 8px;
            border-color: var(--border-color);
            border-style: solid;
            height: 30px;min-width: 20px
        }
        `
        document.head.appendChild(style)
    },

    async beforeRegisterNodeDef(nodeType, nodeData, app) {
        if (nodeData.name === "FCL_SELECT_AREA") {

            const onNodeCreated = nodeType.prototype.onNodeCreated

            nodeType.prototype.onNodeCreated = async function () {
                const r = onNodeCreated
                    ? onNodeCreated.apply(this, arguments)
                    : undefined;

                const area_widget = {
                    type: 'ALIST',
                    name: "area_list",
                    draw(ctx, node, widget_width, y, widget_height) {
                        Object.assign(
                            {},
                            {
                                "display": "none"
                            }
                        )
                    },
                    parent: this,
                }
                this.addCustomWidget(area_widget)

                const width = this.widgets.filter(w => w.name == 'width')[0]
                const height = this.widgets.filter(w => w.name == 'height')[0]
                const area_list = this.widgets.filter(w => w.name == 'area_list')[0]
                console.log("widgets", this.widgets);
                var nodeName = "FCL_SELECT_AREA";
                nodeObj.apply(this, [this, nodeName, { "width": width, "height": height, "area_list": area_list }, app])
                console.log('area_list', area_list);
                this.setSize([800, 1024]);
                this.onResize = function () {
                    let [w, h] = this.size
                    let width = 800;
                    let height = 1024;
                    if (w <= width) w = width
                    if (h <= height) h = height

                    if (w > width) {
                        h = w + 20
                    }

                    this.size = [w, h]
                }


                /*  const w = ComfyWidgets["STRING"](this, "result", ["STRING", { multiline: true }], app).widget;
                 w.inputEl.readOnly = true;
                 w.inputEl.style.opacity = 0.6;
                 w.value = "aa"; */



                return r
            }

            const onExecuted = nodeType.prototype.onExecuted;
            nodeType.prototype.onExecuted = function (message) {
                const r = onExecuted?.apply?.(this, arguments);
                console.log('开始执行')
                console.log(message)
                /* let json = message.json
                console.log(json)
                if (json) {
                    json = {
                        width: 111,
                        height: 222
                    }
                    // area_list.value = JSON.stringify(json, null, 2)
                } */

                return r
            }

        }
    },


    async loadedGraphNode(node, app) {
        if (node.type === 'FCL_SELECT_AREA') {
            try {

                const width = height = 512;
                console.log("aaaaaaaaaaaaaaaa ");
            } catch (error) { }
        }
    }
});
